﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using Tulde.WindowsPhone.Music.ViewModel;
using System.IO.IsolatedStorage;
using System.IO;
using System.Xml.Serialization;
using System.Diagnostics;

namespace Tulde.WindowsPhone.Music
{
    public static class SecurityProvider
    {
        private const string AUTH_TOKEN_FILE = "xxauthtokenxxxxx";
        public static bool IsAuthenticated { get; private set; }

        private static ICredentials _Credentials
        {
            get;
            set;
        }


        public static void RestoreCredentials()
        {
            var x = LoadCredentials();
            if (x != null)
            {
                SetCredentials(x);
            }
            Token = LoadToken();
        }
        public static NetworkCredential Credentials { get; set; }
       
        public static AuthenticationToken Token { get; private set; }
        public static event EventHandler<SecurityProviderEventArgs<ICredentials>> CredentialsChanged;
        public static event EventHandler<SecurityProviderEventArgs<AuthenticationToken>> TokenChanged;
        public static void SetCredentials(ICredentials credentials)
        {
            _Credentials = credentials;
            Credentials = _Credentials.GetCredential(null, "");
            if (CredentialsChanged != null)
            {
                CredentialsChanged(null, new SecurityProviderEventArgs<ICredentials> { Source = Credentials });
            }
        }
        public static void SetAuthenticationTokens( AuthenticationToken token)
        {
            Token = token;
            IsAuthenticated = true;
            if (token != null)
            {
                SaveToken();
            }
            if (TokenChanged != null)
            {
                TokenChanged(null, new SecurityProviderEventArgs<AuthenticationToken> { Source = token });
            }
        }
        public static ICredentials LoadCredentials()
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Mp3TunesCredentials));
            //FileStream file = new FileStream(strPath, FileMode.OpenOrCreate);
            Mp3TunesCredentials oProfile = null;
            using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
            {

                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("_234124.store", System.IO.FileMode.OpenOrCreate, isf))
                {
                    if (stream.Length > 0)
                    {
                        oProfile = (Mp3TunesCredentials)serializer.Deserialize(stream);
                    }
                }
            }
            Debug.WriteLine("Loaded Credentials" + (oProfile != null ? oProfile.Token : ""));
            return oProfile;
        }
        private static AuthenticationToken LoadToken()
        {
            XmlSerializer serializer = new XmlSerializer(typeof(AuthenticationToken));
            //FileStream file = new FileStream(strPath, FileMode.OpenOrCreate);
            AuthenticationToken oProfile = null;
            using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
            {

                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(AUTH_TOKEN_FILE, System.IO.FileMode.OpenOrCreate, isf))
                {
                    if (stream.Length > 0)
                    {
                        oProfile = (AuthenticationToken)serializer.Deserialize(stream);
                    }
                }
            }
            Debug.WriteLine("Loaded Token" + (oProfile != null ? oProfile.SessionID : ""));
            return oProfile;
        }
        public static void SaveCredentials(ICredentials c)
        {
            using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
            {
                MemoryStream ms = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(c.GetType());
                xs.Serialize(ms, c);

                ms.Seek(0, SeekOrigin.Begin);
                using (ms)
                {
                    IsolatedStorageFileStream file_stream = isf.CreateFile("_234124.store");
                    if (file_stream == null) throw new Exception();
                    int READ_CHUNK = 1024 * 1024;
                    int WRITE_CHUNK = 1024 * 1024;
                    byte[] buffer = new byte[READ_CHUNK];
                    while (true)
                    {
                        int read = ms.Read(buffer, 0, READ_CHUNK);
                        if (read <= 0) break;
                        int to_write = read;
                        while (to_write > 0)
                        {
                            file_stream.Write(buffer, 0, Math.Min(to_write, WRITE_CHUNK));
                            to_write -= Math.Min(to_write, WRITE_CHUNK);
                        }
                    }

                    file_stream.Close();
                }

            }
            if( Token != null)
                SaveToken();
        }
        private static void SaveToken()
        {
            
            using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
            {
                MemoryStream ms = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(Token.GetType());
                xs.Serialize(ms, Token);

                ms.Seek(0, SeekOrigin.Begin);
                using (ms)
                {
                    IsolatedStorageFileStream file_stream = isf.CreateFile(AUTH_TOKEN_FILE);
                    if (file_stream == null) throw new Exception();
                    int READ_CHUNK = 1024 * 1024;
                    int WRITE_CHUNK = 1024 * 1024;
                    byte[] buffer = new byte[READ_CHUNK];
                    while (true)
                    {
                        int read = ms.Read(buffer, 0, READ_CHUNK);
                        if (read <= 0) break;
                        int to_write = read;
                        while (to_write > 0)
                        {
                            file_stream.Write(buffer, 0, Math.Min(to_write, WRITE_CHUNK));
                            to_write -= Math.Min(to_write, WRITE_CHUNK);
                        }
                    }

                    file_stream.Close();
                }

            }
        }
        public static void ClearCredentials()
        {
            using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
            {
                try
                {
                    isf.DeleteFile("_234124.store");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "An error occured.", MessageBoxButton.OK);
                }
                try
                {
                    isf.DeleteFile(AUTH_TOKEN_FILE);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "An error occured.", MessageBoxButton.OK);
                }
              
            }
        }
    }
    public class SecurityProviderEventArgs<T> : EventArgs
    {
        public T Source { get; set; }
    }
}
